package no.ntnu.item.ttm4115.termproject.groupagent;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.thoughtworks.xstream.XStream;

import no.ntnu.item.ttm4115.termproject.RegisterGA;
import no.tellu.common.javaframe.ActorAddress;
import no.ntnu.item.ttm4115.termproject.RegisterPlayer;
import no.ntnu.item.ttm4115.termproject.extrasagent.Group;
import no.ntnu.item.ttm4115.termproject.extrasagent.Player;

import no.ntnu.item.ttm4115.termproject.GetGroupMemberInfoToDiscussion;

import no.ntnu.item.ttm4115.termproject.GCAGstartedToGa;
import no.ntnu.item.ttm4115.termproject.StartedGroupChatToPlayers;
import no.ntnu.item.ttm4115.termproject.InformGroupAboutDiscussion;

import no.ntnu.item.ttm4115.termproject.StartUpGame;
import no.ntnu.item.ttm4115.termproject.NewClue;
import no.ntnu.item.ttm4115.termproject.ForwardedClue;
import no.ntnu.item.ttm4115.termproject.ForwardCoordsToGA;
import no.ntnu.item.ttm4115.termproject.ForwardCoordsToGM;
import no.ntnu.item.ttm4115.termproject.TARefrence;
import no.tellu.common.javaframe.messages.RoleRequestMsg;
import no.tellu.common.actorframe.messages.RoleDeniedMsg;
import no.tellu.common.actorframe.messages.RoleConfirmMsg;
import no.ntnu.item.ttm4115.termproject.InfoForGGAgent;
import no.ntnu.item.ttm4115.termproject.InformGGANewPlayer;
import no.ntnu.item.ttm4115.termproject.SendGroupPlayersToPA;
import no.ntnu.item.ttm4115.termproject.PositionToGroupAgent;
import no.ntnu.item.ttm4115.termproject.DistributePosition;
import no.ntnu.item.ttm4115.termproject.RegisterPlayerPositionAgent;
import no.ntnu.item.ttm4115.termproject.GameEnd;




public class GroupAgentActions extends Object {

	public static void initialize(GroupAgentSM asm){
	    // 
	asm.sendMessage(new RegisterGA(asm.getMyActorAddress()), new ActorAddress("/classManager","ClassManager"));
	}

	public static void sendLoggedInUsers(GCAGstartedToGa signal, GroupAgentSM asm){

		asm.ongoingGroupChat = 1;
		Iterator<Entry<String, Player>> iterator = asm.onlinePlayers.entrySet().iterator();
		while(iterator.hasNext()){
			
			Map.Entry<String, Player> me = (Map.Entry<String, Player>)iterator.next();
			asm.sendMessage(new StartedGroupChatToPlayers(signal.getSenderRole(), asm.groupsName), me.getValue().getActorAddress());
		
		}
	}

	public static void sendGroupMemberInfoToDiscussion(GetGroupMemberInfoToDiscussion signal, GroupAgentSM asm){
	    
		asm.ongoingGroupDiscussion = 1;
		Iterator<Entry<String, Player>> iterator = asm.onlinePlayers.entrySet().iterator();
		
	    while(iterator.hasNext()){
	
	    	 Map.Entry<String, Player> me = (Map.Entry<String, Player>) iterator.next();
			 asm.sendMessage(new InformGroupAboutDiscussion(signal.groupDiscussionAgent, asm.groupsName), me.getValue().getActorAddress());
				
		    }
	}

	public static void playerRegistration(RegisterPlayer signal, GroupAgentSM asm){
		   asm.groupsName = signal.groupName;
		    XStream xstream = new XStream();
			xstream.setClassLoader(new Player().getClass().getClassLoader());
			xstream.alias("player", Player.class);
			xstream.alias("group", Group.class);
			xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
			
			Object object = (Object)xstream.fromXML(signal.playerXML);
			Player player = (Player)object;
		    
			player.setActorAddress(signal.getSenderRole());
			System.out.println(asm.groupsName+" mottok spiller "+player.getUserName());
		    
			if(!asm.onlinePlayers.containsKey(player.getUserName())) {
		    	asm.onlinePlayers.put(player.getUserName(), player);	
			}
			
			if(!asm.onlinePlayersShort.containsKey(player.getUserName())) {
				asm.onlinePlayersShort.put(player.getUserName(), player.getActorAddress());	
			}
			
		    Iterator<Entry<String, Player>> iterator = asm.onlinePlayers.entrySet().iterator();
		    
			while(iterator.hasNext()){
				 Map.Entry<String, Player> me = (Entry<String, Player>) iterator.next();
					
					String xmlGroupPlayers = xstream.toXML(asm.onlinePlayersShort);
				 
				 asm.sendMessage(new SendGroupPlayersToPA(xmlGroupPlayers, asm.groupsName), me.getValue().getActorAddress() );
					
			    }			
	}

	public static void distributeClue(NewClue signal, GroupAgentSM asm){
		asm.myGameManagerAgent = signal.getSenderRole();
		
		Iterator iterator2 = asm.onlinePlayers.entrySet().iterator();
		
	    while(iterator2.hasNext()){
	    	Map.Entry<String, Player> me = (Map.Entry)iterator2.next();
	    	for(int i=0; i<me.getValue().getGroups().size(); i++){
	    		if(me.getValue().getGroups().get(i).getGroupName().equals(asm.groupsName)){
	    			asm.groupLeader = me.getValue().getGroups().get(i).getLeader();
	    		}
	    				
	    	}
	    	
	    	
		
	    }
		
		Iterator iterator = asm.onlinePlayers.entrySet().iterator();
		
		
		
	    while(iterator.hasNext()){
	    	Map.Entry<String, Player> me = (Map.Entry)iterator.next();
	    	asm.sendMessage(new ForwardedClue(signal.Clue,signal.gameName, asm.groupLeader),(ActorAddress) me.getValue().getActorAddress());
		
	}
	}

	public static void sendCoordsToGM(ForwardCoordsToGA signal, GroupAgentSM asm){
	    System.out.println("dette er gamemanager adressen"+asm.myGameManagerAgent);
	    asm.sendMessage(new ForwardCoordsToGM(signal.xCoord, signal.yCoord),asm.myGameManagerAgent);
	}

	public static void startUpGGAgent(TARefrence signal, GroupAgentSM asm){
	asm.currentTreasureAddress = signal.treasureAddress;
	String Agentnumber = "GGAgent"+asm.GGAgentNumber;
	asm.sendMessage(new RoleRequestMsg(Agentnumber,"GroupGameAgent"),asm.getMyActorAddress());
	asm.GGAgentNumber++;
	}

	public static void roleDeniedHandling(RoleDeniedMsg signal, GroupAgentSM asm){
	    // 
	}

	public static void sendInformationForQA(RoleConfirmMsg signal, GroupAgentSM asm){
	asm.myGameAgent= signal.getSenderRole();
	asm.gameExsists = true;
	System.out.println(asm.currentTreasureAddress);
	System.out.println(asm.currentTreasureAddress);
	System.out.println(asm.currentTreasureAddress);
	asm.sendMessage(new InfoForGGAgent(asm.onlinePlayers,asm.currentTreasureAddress, asm.myGameManagerAgent), signal.getSenderRole());
	}

	public static boolean noGameForGroup(RegisterPlayer signal, GroupAgentSM asm){
	    if(asm.gameExsists==true){
	    	return false;
	    }
	    	return true;
	}

	public static void informGroupGameNewPlayer(RegisterPlayer signal, GroupAgentSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object object = (Object)xstream.fromXML(signal.playerXML);
		Player player = (Player)object;
		
		asm.sendMessage(new InformGGANewPlayer(player), asm.myGameAgent);
		if(!asm.onlinePlayers.containsKey(player.getUserName())) {
			asm.onlinePlayers.put(player.getUserName(), player);	
		}
	

			
		Iterator iterator = asm.onlinePlayers.entrySet().iterator();				
			while(iterator.hasNext()){
				Map.Entry<String, Player> me = (Map.Entry)iterator.next();
				String xmlGroupPlayers = xstream.toXML(asm.onlinePlayers);
				asm.sendMessage(new SendGroupPlayersToPA(xmlGroupPlayers, asm.groupsName), me.getValue().getActorAddress());
			}	

	}

	public static void distributeLocation(PositionToGroupAgent signal, GroupAgentSM asm){
		Iterator iterator = asm.playerPositionAgentAddresses.entrySet().iterator();				
		while(iterator.hasNext()){
			Map.Entry<String, ActorAddress> me = (Map.Entry)iterator.next();	
			asm.sendMessage(new DistributePosition(signal.lon,signal.lat,signal.myPlayerName), me.getValue());
		}
	}
	
	public static void registerPlayerPositionAgents(RegisterPlayerPositionAgent signal, GroupAgentSM asm){
	    asm.playerPositionAgentAddresses.put(signal.playerName, signal.playerPositionAgentAddress);
	}

	public static void gameEnded(GameEnd signal, GroupAgentSM asm){
	    // 
			System.out.println("Game Ended and inform to the players");
	
			Iterator iterator = asm.onlinePlayers.entrySet().iterator();
	
			while(iterator.hasNext()){
				Map.Entry<String, Player> me = (Map.Entry)iterator.next();
	
				System.out.println("****************** "+me.getValue().getActorAddress());
				//asm.sendMessage(new ForwardedClue(signal.Clue,signal.gameName, asm.groupLeader),(ActorAddress) me.getValue().getActorAddress());
				asm.sendMessage(signal, (ActorAddress) me.getValue().getActorAddress());
			}

	}
}